package org.goyo.main.servlet.captcha;

import com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;
import com.octo.captcha.component.image.backgroundgenerator.UniColorBackgroundGenerator;
import com.octo.captcha.component.image.color.RandomListColorGenerator;
import com.octo.captcha.component.image.deformation.ImageDeformation;
import com.octo.captcha.component.image.deformation.ImageDeformationByFilters;
import com.octo.captcha.component.image.fontgenerator.FontGenerator;
import com.octo.captcha.component.image.fontgenerator.RandomFontGenerator;
import com.octo.captcha.component.image.textpaster.DecoratedRandomTextPaster;
import com.octo.captcha.component.image.textpaster.TextPaster;
import com.octo.captcha.component.image.textpaster.textdecorator.TextDecorator;
import com.octo.captcha.component.image.wordtoimage.DeformedComposedWordToImage;
import com.octo.captcha.component.image.wordtoimage.WordToImage;
import com.octo.captcha.component.word.FileDictionary;
import com.octo.captcha.component.word.wordgenerator.ComposeDictionaryWordGenerator;
import com.octo.captcha.component.word.wordgenerator.WordGenerator;
import com.octo.captcha.engine.image.ListImageCaptchaEngine;
import com.octo.captcha.image.ImageCaptcha;
import com.octo.captcha.image.gimpy.GimpyFactory;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.awt.image.ImageFilter;
import java.io.IOException;
import java.io.OutputStream;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * JCaptcha验证码图片生成引擎,仿照JCaptcha2.0编写类似GMail验证码的样式.
 * 
 * @author liu
 * 
 */
public class GMailEngine extends ListImageCaptchaEngine {
  private static Logger logger = LoggerFactory.getLogger(GMailEngine.class);

  private static GMailEngine instance = new GMailEngine();

  ImageCaptcha imageCaptcha = null;

  /*
   * public static final String IMAGE_CAPTCHA_KEY = "imageCaptcha";// ImageCaptcha对象存放在Session中的key
   * public static final String CAPTCHA_INPUT_NAME = "j_captcha";// 验证码输入表单名称 public static final
   * String CAPTCHA_IMAGE_URL = "/captcha.jpg";// 验证码图片URL private static final Integer
   * MIN_WORD_LENGTH = 4;// 验证码最小长度 private static final Integer MAX_WORD_LENGTH = 4;// 验证码最大长度
   * private static final Integer IMAGE_HEIGHT = 28;// 验证码图片高度 private static final Integer
   * IMAGE_WIDTH = 80;// 验证码图片宽度 private static final Integer MIN_FONT_SIZE = 16;// 验证码最小字体 private
   * static final Integer MAX_FONT_SIZE = 16;// 验证码最大字体 private static final String RANDOM_WORD =
   * "ABCDEFGHIJKLMNOPQRSTUVWXYZ";// 随机字符 private static final String IMAGE_PATH =
   * "./com/zsw/captcha/";// 随机背景图片路径
   * 
   * // 验证码随机字体 private static final Font[] RANDOM_FONT = new Font[] { new Font("nyala", Font.BOLD,
   * MIN_FONT_SIZE), new Font("Arial", Font.BOLD, MIN_FONT_SIZE), new Font("Bell MT", Font.BOLD,
   * MIN_FONT_SIZE), new Font("Credit valley", Font.BOLD, MIN_FONT_SIZE), new Font("Impact",
   * Font.BOLD, MIN_FONT_SIZE) }; // 验证码随机颜色 private static final Color[] RANDOM_COLOR = new Color[]
   * { new Color(255, 255, 255), new Color(255, 220, 220), new Color(220, 255, 255), new Color(220,
   * 220, 255), new Color(255, 255, 220), new Color(220, 255, 220) }; // 生成验证码
   * 
   * @Override protected void buildInitialFactories() {
   * 
   * RandomListColorGenerator randomListColorGenerator = new
   * RandomListColorGenerator(RANDOM_COLOR);// 验证码随机颜色 BackgroundGenerator backgroundGenerator = new
   * UniColorBackgroundGenerator(IMAGE_WIDTH, IMAGE_HEIGHT, Color.BLUE); //验证码背景图片 WordGenerator
   * wordGenerator = new RandomWordGenerator(RANDOM_WORD);new ComposeDictionaryWordGenerator( new
   * FileDictionary("toddlist")); FontGenerator fontGenerator = new
   * RandomFontGenerator(MIN_FONT_SIZE, MAX_FONT_SIZE, RANDOM_FONT);// 验证码随机字体 TextDecorator[]
   * textDecorator = new TextDecorator[] {}; TextPaster textPaster = new
   * DecoratedRandomTextPaster(MIN_WORD_LENGTH, MAX_WORD_LENGTH, randomListColorGenerator,
   * textDecorator); WordToImage wordToImage = new ComposedWordToImage(fontGenerator,
   * backgroundGenerator, textPaster); addFactory(new GimpyFactory(wordGenerator, wordToImage)); }
   */

  private GMailEngine() {}

  public static GMailEngine getInstance() {
    return instance;
  }

  @Override
  protected void buildInitialFactories() {
    int minWordLength = 4;
    int maxWordLength = 5;
    int fontSize = 24;
    int imageWidth = 100;
    int imageHeight = 45;
    WordGenerator dictionnaryWords =
        new ComposeDictionaryWordGenerator(new FileDictionary("toddlist"));

    // word2image components
    TextPaster randomPaster =
        new DecoratedRandomTextPaster(minWordLength, maxWordLength, new RandomListColorGenerator(
            new Color[] {new Color(23, 170, 27), new Color(220, 34, 11), new Color(23, 67, 172)}),
            new TextDecorator[] {});
    BackgroundGenerator background =
        new UniColorBackgroundGenerator(imageWidth, imageHeight, Color.white);
    FontGenerator font =
        new RandomFontGenerator(fontSize, fontSize, new Font[] {
            new Font("nyala", Font.BOLD, fontSize), new Font("Bell MT", Font.PLAIN, fontSize),
            new Font("Credit valley", Font.BOLD, fontSize)});
    ImageDeformation postDef = new ImageDeformationByFilters(new ImageFilter[] {});
    ImageDeformation backDef = new ImageDeformationByFilters(new ImageFilter[] {});
    ImageDeformation textDef = new ImageDeformationByFilters(new ImageFilter[] {});

    WordToImage word2image =
        new DeformedComposedWordToImage(font, background, randomPaster, backDef, textDef, postDef);
    addFactory(new GimpyFactory(dictionnaryWords, word2image));
  }

  /**
   * Write the captcha image of current user to the servlet response
   * 
   * @param request HttpServletRequest
   * @param response HttpServletResponse
   * @throws IOException
   */
  public void writeCaptchaImage(HttpServletRequest request, HttpServletResponse response)
      throws IOException {
    imageCaptcha = getNextImageCaptcha();
    HttpSession session = request.getSession();
    session.setAttribute("imageCaptcha", imageCaptcha);
    BufferedImage image = (BufferedImage) imageCaptcha.getChallenge();

    OutputStream outputStream = null;
    try {
      outputStream = response.getOutputStream();

      response.setDateHeader("Expires", 1L);
      response.addHeader("Pragma", "no-cache");
      // Http 1.1 header
      response.setHeader("Cache-Control", "no-cache, no-store, max-age=0");
      response.setContentType("image/jpeg");

      /*
       * JPEGImageEncoder encoder = JPEGCodec .createJPEGEncoder(outputStream);
       * encoder.encode(image);
       */
      ImageIO.write(image, "jpg", outputStream);
      outputStream.flush();
      outputStream.close();
      outputStream = null;// no close twice
    } catch (IOException ex) {
      logger.error("产生图片异常 ＝＝ " + ex);
      throw ex;
    } finally {
      if (outputStream != null) {
        try {
          outputStream.close();
        } catch (IOException ex) {
        }
      }
      imageCaptcha.disposeChallenge();
    }
  }


}
